package com.asa.information;

/**
 * 香农
 * 
 * @author asa
 *
 *         先按人来分吧，要怎么分还不填清楚
 *
 */
public class Shannon {

	/**
	 * JointEntropy和ConditionalEntropy都只是它的概念变形
	 * @param asa double数组，里面的值放概率，需要大于等于0，小于等于1
	 * @param e   log以哪个数为底
	 * @return 香农熵
	 */
	public static double ShannonEntropy(double[] asa, Double e) {

		for (int i = 0; i < asa.length; i++) {
			if (asa[i] < 0 || asa[i] > 1) {
				throw new RuntimeException("asa参数错误，要求大于等于0，小于等于1");
			}
		}

		double result = 0;

		for (int i = 0; i < asa.length; i++) {

			if (asa[i] == 0)
				continue;

			if (e == null) {
				result += Math.log(asa[i]);
			} else {
				result += Math.log(asa[i]) / Math.log(e);
			}
		}
		return result;
	}

	/**
	 * 
	 * @param asa 联合概率，单个的概率
	 * @param e
	 * @return
	 */
	public static double JointEntropy(double asa, Double e) {
		if (asa < 0 || asa > 1) {
			throw new RuntimeException("asa参数错误，要求大于等于0，小于等于1");
		}
		double result = 0;

		if (asa == 0) {
			return 0;
		}

		if (e == null) {
			result += Math.log(asa);
		} else {
			result += Math.log(asa) / Math.log(e);
		}

		return result;
	}
	
	
	
	/**
	 * 当一个发生，另一个也发生的概率
	 * @param asa
	 * @param e
	 * @return
	 */
	
	public static double ConditionalEntropy(double asa, Double e) {
		if (asa < 0 || asa > 1) {
			throw new RuntimeException("asa参数错误，要求大于等于0，小于等于1");
		}
		double result = 0;

		if (asa == 0) {
			return 0;
		}

		if (e == null) {
			result += Math.log(asa);
		} else {
			result += Math.log(asa) / Math.log(e);
		}

		return result;
	}
	
	
	
	
	

}
